package top.wbhzx.wangpan.auth;

import com.alibaba.fastjson.JSON;
import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
import top.wbhzx.wangpan.redis.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.crypto.bcrypt.BCrypt;
import org.springframework.stereotype.Service;
import java.util.Date;

/**
 * @Author: JiangZuoWei,WangZhiXian
 * @Description:
 * @Date: Create in 19:23 2019-05-27
 */
@Service
public class AuthServiceImpl implements AuthService {

    /**
     * redis操作工具
     */
    @Autowired
    private RedisUtil redisUtil;

    /**
     * 有效时间
     */
    @Value("${uxunchina.common.redisCacheExpireSeconds}")
    private int expireSeconds;

    /**
     * 加密的盐
     */
    @Value("${TOKEN_SALT_WBHZX}")
    private String tokenSalt;

    @Value("${TOKEN_WBHZX}")
    private String tokenKey;

    /**
     * 根据token得到用户信息
     * @param token
     * @return
     */
    @Override
    public UserInfo getUserInfo(String token) {
        // token解密 ->  tokenKey + key
        DecodedJWT jwt = JWT.decode(token);
        // 解密出key用来查redis
        String cacheStr = redisUtil.get(jwt.getSubject());
        if (null != cacheStr && !"".equals(cacheStr)) {
            // json解析为javaBean
            UserInfo dto = JSON.parseObject(cacheStr, UserInfo.class);
            if (null != dto) {
                // 跟新tonken的有效时间
                this.redisUtil.setWithExpireTime(tokenSalt + dto.getUserId().toString(), redisUtil.get(tokenSalt + dto.getUserId()), this.expireSeconds);
                this.redisUtil.setObject(tokenKey + dto.getUserId().toString(), dto, this.expireSeconds);
                return dto;
            }
        }
        return null;
    }

    /**
     * 根据key创建Token
     * @param key
     * @return
     */
    @Override
    public String createToken(String key) {
        // 得到随机的盐
        String salt = BCrypt.gensalt();
        // 用用户id将得到的盐存入redis
        this.redisUtil.setWithExpireTime(tokenSalt + key, salt, this.expireSeconds);
        // 加密算法生成签名
        Algorithm algorithm = Algorithm.HMAC256(salt);
        // 注册签名
        Date date = new Date(System.currentTimeMillis() + this.expireSeconds * 1000);
        return JWT.create().withSubject(tokenKey + key).withExpiresAt(date).withIssuedAt(new Date()).sign(algorithm);
    }

    /**
     * 根据key和values创建
     * @param key
     * @param val
     * @return
     */
    @Override
    public String createToken(String key, Object val) {
        String jwtToken = createToken(key);
        this.redisUtil.setObject(tokenKey + key, val, this.expireSeconds);
        return jwtToken;
    }

    /**
     * 删除Token
     * @param paramString
     */
    @Override
    public void delToken(String paramString) {
        this.redisUtil.delete(paramString);
        this.redisUtil.delete(tokenSalt + paramString);
    }

    /**
     * 重置有效时间
     * @param token
     */
    @Override
    public void expireKey(String token) {
        redisUtil.expireKey(token,expireSeconds);
    }

    @Override
    public void initLogin(String userId) {

    }
}
